package com.jjrwa.transform;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.*;
import com.jjrwa.component.EntityTransformTable;
import com.jjrwa.component.TableDataHandle;
import com.jjrwa.define.HandleClass;
import com.jjrwa.define.HandleClassField;
import com.jjrwa.from.BuildClassTable;
import com.jjrwa.from.UIFieldTable;
import com.jjrwa.utils.CommonUtils;
import com.jjrwa.utils.FileHandleUtils;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 处理器
 */
public abstract class EntityTransformHandler {

    /**
     * 转换为vo类
     *
     * @param event
     */
    public static void entityToVo(AnActionEvent event) {
        entityTransform(event, new ITransform() {
            @Override
            public String modelType() {
                return "vo";
            }

            @Override
            public void customHandleClass(PsiClass entityClass, HandleClass handleClass) {
                String description = handleClass.getDescription();
                handleClass.setDescription(description + "视图");
                handleClass.setQueryName(description + "分页查询");
                handleClass.setEntityClassName(entityClass.getName());
                handleClass.setEntityClassNameParam(CommonUtils.firstLowerCase(entityClass.getName()));
                handleClass.setSerialVersionUIDValue(CommonUtils.buildSerialVersionUID());
            }

            @Override
            public void importHandle(Set<String> importContent, PsiJavaFile javaFile, PsiClass entityClass) {
                //把实体类包先放入
                importContent.add(entityClass.getQualifiedName());
            }

            @Override
            public String templateName() {
                return "entityToVo.ftl";
            }

        });
    }

    public static void entityToParam(AnActionEvent event) {
        entityTransform(event, new ITransform() {
            @Override
            public String modelType() {
                return "param";
            }

            @Override
            public void customHandleClass(PsiClass entityClass, HandleClass handleClass) {
                handleClass.setDescription(handleClass.getDescription() + "参数");
            }

            @Override
            public String templateName() {
                return "entityToParam.ftl";
            }
        });
    }

    public static void entityToProvide(AnActionEvent event) {
        entityTransform(event, new ITransform() {
            @Override
            public String modelType() {
                return "provide";
            }

            @Override
            public void customHandleClass(PsiClass entityClass, HandleClass handleClass) {
                handleClass.setDescription(handleClass.getDescription() + "接口");
            }

            @Override
            public String templateName() {
                return "entityToProvide.ftl";
            }
        });
    }

    public static void entityToProvideMyBatis(AnActionEvent event) {
        entityTransform(event, new ITransform() {
            @Override
            public String modelType() {
                return "mapper";
            }

            @Override
            public void customHandleClass(PsiClass entityClass, HandleClass handleClass) {
                handleClass.setDescription(handleClass.getDescription() + "接口");
            }

            @Override
            public void importHandle(Set<String> importContent, PsiJavaFile javaFile, PsiClass entityClass) {
                //把实体类包先放入
                importContent.add(entityClass.getQualifiedName());
            }
            @Override
            public String templateName() {
                return "entityToProvideMybatis.ftl";
            }
        });
    }

    private static void entityTransform(AnActionEvent event, ITransform transform) {
        PsiJavaFile javaFile = FileHandleUtils.getPsiJavaFile(event);
        if (javaFile == null) {
            return;
        }

        //实体类紧紧包含一个class文件
        PsiClass entityClass = javaFile.getClasses()[0];

        //是否配置@Entity 实体类
        PsiAnnotation entityAnn = entityClass.getAnnotation("javax.persistence.Entity");
        if (entityAnn == null) {
            throw new RuntimeException("仅支持实体类的转换");
        }
        //获取实体描述
        PsiAnnotation apiModelAnn = entityClass.getAnnotation("io.swagger.annotations.ApiModel");
        if (apiModelAnn == null) {
            throw new RuntimeException("实体类未配置@ApiModel");
        }
        PsiAnnotationMemberValue memberValue = apiModelAnn.findAttributeValue("description");
        if (null == memberValue) {
            throw new RuntimeException("实体类配置的@ApiModel注解中，未给description字段赋值");
        }
        //实体描述
        String classDescription = memberValue.getText().replace("\"", "");

        //className
        String className = entityClass.getName() + CommonUtils.firstToUpperCase(transform.modelType());

        //自定义处理
        HandleClass handleClass = new HandleClass();
        handleClass.setClassName(className);
        handleClass.setOldClassName(entityClass.getName());
        handleClass.setDescription(classDescription);
        transform.customHandleClass(entityClass, handleClass);

        //导入类容
        Set<String> importContent = new HashSet<>();
        transform.importHandle(importContent, javaFile, entityClass);

        //字段处理
        List<HandleClassField> fields = new ArrayList<>();
        PsiField[] allFields = entityClass.getFields();
        for (PsiField psiField : allFields) {
            PsiAnnotation propertyAnn = psiField.getAnnotation("io.swagger.annotations.ApiModelProperty");
            if (propertyAnn == null) {
                continue;
            }
            PsiAnnotationMemberValue annValue = propertyAnn.findAttributeValue("value");
            String fieldDescription;
            if (annValue == null || annValue.getText() == null) {
                fieldDescription = psiField.getName();
            } else {
                fieldDescription = annValue.getText().replace("\"", "");
            }
            PsiType type = psiField.getType();

            //加入字段中
            fields.add(new HandleClassField(psiField.getName(), fieldDescription, type.getPresentableText()));

            if (CommonUtils.needImport(type)) {
                importContent.add(type.getInternalCanonicalText());
            }
        }
        handleClass.setImportContent(importContent);
        handleClass.setFields(fields);

        //表格通用处理
        IClassTable iClassTable = new IClassTable() {
            @Override
            public String getTitle() {
                return "Create " + CommonUtils.firstToUpperCase(transform.modelType())
                        + " Class";
            }

            @Override
            public String getClassName() {
                return handleClass.getClassName();
            }

            @Override
            public String getClassDescription() {
                return handleClass.getDescription();
            }
        };

        IButtonEvent okButtonEvent = new IButtonEvent() {
            @Override
            public boolean handle(MouseEvent e, JFrame jFrame, JTextField classNameText, JTextField descriptionText) {
                handleClass.setClassName(classNameText.getText());
                handleClass.setDescription(descriptionText.getText());

                PsiDirectory containingDirectory = javaFile.getContainingDirectory();
                PsiDirectory parentDirectory = containingDirectory.getParentDirectory();

                // runWriteAction 包裹写操作
                ApplicationManager.getApplication().runWriteAction(() -> {
                    PsiDirectory childDirectory = parentDirectory.findSubdirectory(transform.modelType());
                    if (childDirectory == null) {
                        childDirectory = parentDirectory.createSubdirectory(transform.modelType());
                    } else {
                        boolean b = FileHandleUtils.checkClassName(childDirectory, handleClass.getClassName());
                        if (!b) {
                            return;
                        }
                    }
                    // 创建 Java 文件
                    FileHandleUtils.createJavaFile(event, transform.templateName(), handleClass, childDirectory);
                });

                return true;
            }
        };

        IButtonEvent fieldsButtonEvent = new IButtonEvent() {
            @Override
            public void handle(MouseEvent e) {
                if(!transform.modelType().equals("provide") && !transform.modelType().equals("mapper")) {
                    new UIFieldTable(new TableDataHandle<>(
                            HandleClassField.class, handleClass.getFields()), h -> new EntityTransformTable(h));
                }
            }
            @Override
            public Boolean isShowButtonName() {
                if(transform.modelType().equals("provide") || transform.modelType().equals("mapper")) {
                    return false;
                }
                return true;
            }
        };

        new BuildClassTable(iClassTable, okButtonEvent, fieldsButtonEvent);

    }

}
